home *** CD-ROM | disk | FTP | other *** search
- /*
- * BaseWindow.C - abstract base class for window support.
- *
- * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
- * University of Berne, Switzerland
- * All rights reserved.
- *
- * This software may be freely copied, modified, and redistributed
- * provided that this copyright notice is preserved on all copies.
- *
- * You may not distribute this software, in whole or in part, as part of
- * any commercial product without the express consent of the authors.
- *
- * There is no warranty or other guarantee of fitness of this software
- * for any purpose. It is provided solely "as is".
- *
- */
-
- #include "BaseWindow.h"
- #include "list.h"
- #include "Error.h"
- #include "Options.h"
-
- //___________________________________________________________ LineSegment
-
- struct LineSegment
- {
- LineSegment(const Vector& p1, const Vector& p2)
- : from(p1), to(p2) {}
-
- Vector from, to;
- };
-
- typedef LineSegment* LineSegmentPtr;
- declareList(LineList, LineSegmentPtr);
- implementList(LineList, LineSegmentPtr);
-
- //___________________________________________________________ BaseWindow
-
- BaseWindow::BaseWindow()
- : view(NULL), resX(400), resY(400),
- lines(NULL), polys(NULL),
- windowIsOpen(0), buffering(1)
- {}
-
- BaseWindow::~BaseWindow()
- {
- if (view != NULL)
- delete view;
- clearBuffer();
- if (lines != NULL)
- delete lines;
- if (polys != NULL)
- delete polys;
- }
-
- void BaseWindow::open(int width, int height, const rcString& windowName)
- {
- if (windowIsOpen)
- Error(ERR_PANIC, "Window is already open");
-
- windowIsOpen = 1;
- resX = width;
- resY = height;
- name = windowName;
- }
-
- void BaseWindow::close()
- {
- if (!windowIsOpen)
- Error(ERR_PANIC, "close window: but window is not open");
- windowIsOpen = 0;
- }
-
- void BaseWindow::clear()
- {
- if (!windowIsOpen)
- Error(ERR_PANIC, "clear window: but window is not open");
- }
-
- /*
- * If buffering is enabled store the given line segment in the
- * line list. Otherwise transform the segment to screen coordinates
- * and show it on the screen.
- */
-
- void BaseWindow::line(const Vector& from, const Vector& to)
- {
- if (buffering) {
- if (lines == NULL)
- lines = new LineList(1000);
- lines->append(new LineSegment(from, to));
- }
- else if (view == NULL) {
- Error(ERR_PANIC, "no view parameter set");
- }
-
- /*
- * Transform and draw the line without buffering.
- */
- else {
- Vector x = view->transformWorld2Screen(from);
- Vector y = view->transformWorld2Screen(to);
- drawLine((int)x[0], (int)x[1], (int)y[0], (int)y[1]);
- }
- }
-
- /*
- * If buffering is enabled store the given polygon in the
- * poly list. Otherwise transform the polygon to screen coordinates
- * and show it on the screen.
- */
-
- void BaseWindow::polygon(Polygon* p)
- {
- if (buffering) {
- if (polys == NULL)
- polys = new PolygonList(1000);
- polys->append(p);
- }
- else if (view == NULL) {
- Error(ERR_PANIC, "no view parameter set");
- }
- else if (p->numVertices() >= 3) {
- Vector x = view->transformWorld2Screen(p->vertex(0));
- Vector y;
-
- for (register long i=1; i<p->numVertices(); i++) {
- y = view->transformWorld2Screen(p->vertex(i));
- drawLine((int)x[0], (int)x[1], (int)y[0], (int)y[1]);
- x = y;
- }
- y = view->transformWorld2Screen(p->vertex(0));
- drawLine((int)x[0], (int)x[1], (int)y[0], (int)y[1]);
- }
-
- if (!buffering)
- delete p;
- }
-
- /*
- * For all the line segment in the line list and all the polys in the
- * polygon list, transform and bring dem to screen.
- */
-
- void BaseWindow::flush()
- {
- if (view == NULL)
- Error(ERR_PANIC, "no view parameter set");
-
- Vector from, to;
- if (lines != NULL) {
- for (register long i=0; i<lines->count(); i++) {
- from = view->transformWorld2Screen(lines->item(i)->from);
- to = view->transformWorld2Screen(lines->item(i)->to);
- drawLine((int)from[0], (int)from[1], (int)to[0], (int)to[1]);
- }
- }
-
- if (polys != NULL) {
- for (register long i=0; i<polys->count(); i++) {
- Polygon* p = polys->item(i);
- if (p->numVertices() >= 3) {
- from = view->transformWorld2Screen(p->vertex(0));
- for (register long j=1; j<p->numVertices(); j++) {
- to = view->transformWorld2Screen(p->vertex(j));
- drawLine((int)from[0], (int)from[1], (int)to[0], (int)to[1]);
- from = to;
- }
- to = view->transformWorld2Screen(p->vertex(0));
- drawLine((int)from[0], (int)from[1], (int)to[0], (int)to[1]);
- }
- }
- }
- }
-
- void BaseWindow::disableBuffering()
- {
- buffering = 0;
- }
-
- void BaseWindow::enableBuffering()
- {
- buffering = 1;
- }
-
- void BaseWindow::setView(const Vector& eye, const Vector& lookat, const Vector& up,
- real fov)
- {
- if (view != NULL)
- delete view;
- view = new ViewTransform(eye, lookat, up, fov, resX, resY);
-
- if (theOptions.verbose)
- cerr << *view << '\n';
- }
-
- void BaseWindow::setView(const BoundingBox& bbox, const Vector& up, real fov)
- {
- if (view != NULL)
- delete view;
- view = new ViewTransform(bbox, up, fov, resX, resY);
-
- if (theOptions.verbose)
- cerr << *view << '\n';
- }
-
- /*
- * Remove all the line segment und polygon from the buffer.
- */
-
- void BaseWindow::clearBuffer()
- {
- if (lines != NULL) {
- for (register long i=0; i<lines->count(); i++)
- delete lines->item(i);
- lines->remove_all();
- }
- if (polys != NULL) {
- for (register long i=0; i<polys->count(); i++)
- delete polys->item(i);
- polys->remove_all();
- }
- }
-